using UnityEngine;

public struct ParabolicFlight
{
	public float h0;

	private float hn_;

	public float minhn;

	public float ht;

	public Vector3 initialPos;

	public Vector3 landingPos;

	private Vector3 spin_;

	public float k;

	public float dx;

	public float dz;

	public float g;

	public float hn
	{
		get
		{
			return hn_;
		}
		set
		{
			hn_ = Mathf.Max(value, minhn);
		}
	}

	public Vector3 spin
	{
		get
		{
			return spin_;
		}
		set
		{
			spin_ = value;
			g = Physics.gravity.y + value.y;
		}
	}

	public float c
	{
		get
		{
			return 2f * (hn - h0 + k * (h0 - ht)) / (k * (k - 1f));
		}
	}

	public Vector3 initialVelocity
	{
		get
		{
			float num = naturalTimeToLand();
			return new Vector3(dx / num - spin.x * num * 0.5f, vy(num), dz / num - spin.z * num * 0.5f);
		}
	}

	public ParabolicFlight(Vector3 theInitialPos, Vector3 theLandingPos, float theHn, Vector3 theSpin, float playingSurfaceTopY)
	{
		spin_ = Vector3.zero;
		spin_.x = theSpin.x;
		g = Physics.gravity.y + theSpin.y;
		landingPos.y = 0f;
		spin_ = theSpin;
		initialPos = theInitialPos;
		landingPos = theLandingPos;
		hn_ = Mathf.Max(0f, theHn);
		h0 = initialPos.y - playingSurfaceTopY;
		ht = 0f;
		Vector3 vector = new Vector3(initialPos.x, 0f, initialPos.z);
		Vector3 vector2 = landingPos - vector;
		float magnitude = vector2.magnitude;
		Vector3 lhs = new Vector3(0f, 0f, Mathf.Sign(vector2.z) * Mathf.Abs(initialPos.z));
		float num = Vector3.Dot(lhs, vector2.normalized);
		k = num / magnitude;
		minhn = h0 + k * (ht - h0);
		hn_ = Mathf.Max(theHn, minhn);
		dx = landingPos.x - initialPos.x;
		dz = landingPos.z - initialPos.z;
	}

	public float vy(float tt)
	{
		return (2f * (hn - h0) - k * tt * k * tt * g) / (2f * k * tt);
	}

	public float hnToMatchTime(float t)
	{
		return t * t * g * k * (k - 1f) * 0.5f - k * (h0 - ht) + h0;
	}

	public float spinYToMatchTime(float t)
	{
		return c / (t * t) - Physics.gravity.y;
	}

	public void SetSpinYToMatchTime(float t)
	{
		Vector3 vector = spin;
		vector.y = spinYToMatchTime(t);
		spin = vector;
	}

	public float naturalTimeToLand()
	{
		if (Mathf.Abs(g) < 0.0001f)
		{
			return 0f;
		}
		return Mathf.Sqrt(c / g);
	}

	public Vector3 initialVelocityWithTime(float time)
	{
		return new Vector3(dx / time - spin.x * time * 0.5f, vy(time), dz / time - spin.z * time * 0.5f);
	}

	public static Vector3 initialVelocityForSimpleCase(Vector3 initialPosition, Vector3 landingPosition, float apexHeight)
	{
		float num = apexHeight - initialPosition.y;
		float y = Physics.gravity.y;
		float num2 = (float)MathEx.SignZeroPositive(num) * Mathf.Sqrt(2f * Mathf.Abs(y * num));
		MathEx.NullPoints nullPoints = MathEx.FindParabolaNullPoints(y * 0.5f, num2, initialPosition.y - landingPosition.y);
		float max = nullPoints.Max;
		if (max <= 0f)
		{
			return Vector3.zero;
		}
		Vector3 result = (landingPosition - initialPosition) / max;
		result.y = num2;
		return result;
	}
}
